package tech.yixiyun.framework.kuafu.log;

import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.spi.AbstractLogger;
import org.apache.logging.log4j.spi.LoggerRegistry;

import java.net.URI;

public class KuafuLoggerContext extends LoggerContext {

    public KuafuLoggerContext(String name) {
        super(name);
    }
    /**
     * Constructor taking a name and a reference to an external context.
     *
     * @param name The context name.
     * @param externalContext The external context.
     */
    public KuafuLoggerContext(final String name, final Object externalContext) {
        this(name, externalContext, (URI) null);
    }

    /**
     * Constructor taking a name, external context and a configuration URI.
     *
     * @param name The context name.
     * @param externalContext The external context.
     * @param configLocn The location of the configuration as a URI.
     */
    public KuafuLoggerContext(final String name, final Object externalContext, final URI configLocn) {
        super(name, externalContext, configLocn);
    }

    /**
     * Constructor taking a name external context and a configuration location String. The location must be resolvable
     * to a File.
     *
     * @param name The configuration location.
     * @param externalContext The external context.
     * @param configLocn The configuration location.
     */
    public KuafuLoggerContext(final String name, final Object externalContext, final String configLocn) {
        super(name, externalContext, configLocn);
    }


    private final LoggerRegistry<Logger> loggerRegistry = new LoggerRegistry<>();


    /**
     * Obtains a Logger from the Context.
     *
     * @param name The name of the Logger to return.
     * @param messageFactory The message factory is used only when creating a logger, subsequent use does not change the
     *            logger but will log a warning if mismatched.
     * @return The Logger.
     */
    @Override
    public Logger getLogger(final String name, final MessageFactory messageFactory) {
        // Note: This is the only method where we add entries to the 'loggerRegistry' ivar.
        Logger logger = loggerRegistry.getLogger(name, messageFactory);
        if (logger != null) {
            AbstractLogger.checkMessageFactory(logger, messageFactory);
            return logger;
        }

        logger = newInstance(this, name, messageFactory);
        loggerRegistry.putIfAbsent(name, messageFactory, logger);
        return loggerRegistry.getLogger(name, messageFactory);
    }

    /**
     * 记录器如果名字以kuafu开头，就认为是框架用的，默认用ForwardLogger实例化
     * @param ctx
     * @param name
     * @param messageFactory
     * @return
     */
    protected Logger newInstance(final LoggerContext ctx, final String name, final MessageFactory messageFactory) {
        if (name.startsWith("kuafu")) {

            return new kuafuLogger(ctx, name, messageFactory);
        } else {
            return super.newInstance(ctx, name, messageFactory );
        }
    }
}
